package com.utils;


import com.utils.mapper.IDMapper;
import com.utils.mapper.KeyMapper;
import com.utils.mapper.Mapper;
import org.springframework.lang.NonNull;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 集合处理 辅助类
 *
 * @author Daizhiqiang
 * @date 2019/7/1 14:10
 */
public class Streams {

    /**
     * 目标列表是否为空
     *
     * @param lists: 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> boolean isEmpty(Collection<T> lists) {
        return lists == null || lists.isEmpty();
    }

    /**
     * 目标列表是否不为空
     *
     * @param lists: 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> boolean isNotEmpty(Collection<T> lists) {
        return !Streams.isEmpty(lists);
    }


    /**
     * 返回非空列表
     *
     * @param lists: 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    @NonNull
    public static <T> Collection<T> listNotNull(Collection<T> lists) {
        return Streams.isEmpty(lists) ? Collections.emptyList() : lists;
    }


    /**
     * 列表第一个对象
     *
     * @param lists: 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Optional<T> first(List<T> lists) {
        return Optional.ofNullable(Streams.isNotEmpty(lists) ? lists.get(0) : null);
    }

    /**
     * 列表最后一个对象
     *
     * @param lists: 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Optional<T> last(List<T> lists) {
        return Optional.ofNullable(Streams.isNotEmpty(lists) ? lists.get(lists.size() - 1) : null);
    }


    /**
     * map: 映射到另外一个列表
     *
     * @param lists: 目标列表
     * @return 处理后的列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T, R> List<R> map(List<T> lists, Function<T, R> func) {
        return lists.stream().map(func).collect(Collectors.toList());
    }

    /**
     * filter: 过滤列表
     *
     * @param lists: 目标列表
     * @return 处理后的列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> filter(Collection<T> lists, Predicate<T> predicate) {
        return lists.stream().filter(predicate).collect(Collectors.toList());
    }


    /**
     * map: 映射到另外一个列表, 并过滤列表
     *
     * @param lists: 目标列表
     * @return 处理后的列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T, R> List<R> mapAndFilter(Collection<T> lists, Function<T, R> func, Predicate<R> predicate) {
        return lists.stream().map(func).filter(predicate).collect(Collectors.toList());
    }

    /**
     * map: 过滤列表, 并映射到另外一个列表
     *
     * @param lists: 目标列表
     * @return 处理后的列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T, R> List<R> filterAndMap(Collection<T> lists, Predicate<T> predicate, Function<T, R> func) {
        return lists.stream().filter(predicate).map(func).collect(Collectors.toList());
    }


    /**
     * 对流按index 遍历
     *
     * @param stream:              处理流
     * @param consumer(Integer,T): 处理方法(index, 对象)
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> void forEachIndexed(Stream<T> stream, BiConsumer<Integer, T> consumer) {
        stream.reduce(0, (index, t) -> {
            consumer.accept(index, t);
            return index + 1;
        }, Integer::max);
    }


    /**
     * 对列表按index 映射
     *
     * @param lists:           目标列表
     * @param func(Integer,T): 处理方法(index, 对象)
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T, R> List<R> mapIndexed(Collection<T> lists, BiFunction<Integer, T, R> func) {
        List<R> records = new ArrayList<>();
        lists.stream().reduce(0, (index, t) -> {
            records.add(func.apply(index, t));
            return index + 1;
        }, Integer::max);

        return records;
    }

    /**
     * 找出对象的id在ids中的数据，返回一个列表
     *
     * @param lists: 目标列表
     * @param ids:   指定的id列表
     * @return 处理后的列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> listIdsIn(Collection<T> lists, List<Long> ids) {
        Collection<T> records = new ArrayList<>();
        List<IDMapper<T>> ll = Mapper.idMappers(lists);

        Map<Long, IDMapper<T>> objMapById = Streams.toMapById(ll, (v) -> v.id);
        ids.forEach(id -> {
            if (objMapById.containsKey(id)) {
                records.add(objMapById.get(id).obj);
            }
        });


        return records;
    }


    /**
     * 获取子列表
     *
     * @param lists: 目标列表
     * @return 处理后的list
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> List<T> toSubList(List<T> lists, int start, int end) {
        return lists.subList(start, Math.min(end, lists.size()));
    }



    /**
     * 列表按idFunc返回的id作为key转换成map
     *
     * @param lists:     目标列表
     * @param idFunc(T): idFunc函数，返回指定的id
     * @return 处理后的map
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <K extends Number, V> Map<K, V> toMapById(Collection<V> lists, Function<V, K> idFunc) {
        Map<K, V> maps = new HashMap<>();
        lists.forEach(v -> {
            K id = idFunc.apply(v);
            maps.put(id, v);
        });
        return maps;
    }



    /**
     * 列表按keyFunc返回的key转换成map
     *
     * @param lists:      目标列表
     * @param keyFunc(T): keyFunc函数，返回指定的key
     * @return 处理后的map
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Map<String, T> toMapByKey(Collection<T> lists, Function<T, String> keyFunc) {
        Map<String, T> maps = new HashMap<>();
        lists.forEach(v -> {
            String id = keyFunc.apply(v);
            maps.put(id, v);
        });
        return maps;
    }


    /**
     * 转换成按id的分组
     *
     * @param idFunc(T): idFunc函数，返回指定的id
     * @param lists      :     目标列表
     * @return 处理后的map
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <K extends Number, T> Map<K, List<T>> groupById(List<T> lists, Function<T, K> idFunc) {
        return lists.stream().collect(Collectors.groupingBy(idFunc));
    }

    /**
     * 转换成按key的分组
     *
     * @param lists:      目标列表
     * @param keyFunc(T): keyFunc函数，返回指定的key
     * @return 处理后的map
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Map<String, List<T>> groupByKey(List<T> lists, Function<T, String> keyFunc) {
        return lists.stream().collect(Collectors.groupingBy(keyFunc));
    }

    /**
     * 对两个等长不为空的列表合并做index遍历
     *
     * @param list1:            目标列表1
     * @param list2:            目标列表2
     * @param consumer(Integer,Pair<T1,T2>): 处理方法(index, Pair<T1,T2>)
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T1, T2> void zipEachIndexed(List<T1> list1, List<T2> list2, BiConsumer<Integer, Pair<T1, T2>> consumer) {
        if (list1.isEmpty() || list2.isEmpty()) {
            return;
        }
        if (list1.size() != list2.size()) {
            return;
        }

        Streams.forEachIndexed(list1.stream(), (index, v) -> {
            consumer.accept(index, new Pair<>(v, list2.get(index)));
        });

    }

    /**
     * 对两个等长不为空的列表合并并遍历
     *
     * @param list1:       目标列表1
     * @param list2:       目标列表2
     * @param consumer(T1,T2): 处理方法(T1,T2)
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T1, T2> void zipEach(List<T1> list1, List<T2> list2, BiConsumer<T1, T2> consumer) {
        if (list1.isEmpty() || list2.isEmpty()) {
            return;
        }
        if (list1.size() != list2.size()) {
            return;
        }
        Streams.forEachIndexed(list1.stream(), (index, v) -> {
            consumer.accept(v, list2.get(index));
        });

    }


    /**
     * 对目标列表按键值id去重
     *
     * @param lists: 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> districtById(Collection<T> lists) {
        Set<IDMapper<T>> idMappers = new HashSet<>(Mapper.idMappers(lists));
        return idMappers.stream().map(v -> v.obj).collect(Collectors.toList());
    }

    /**
     * 对目标列表按对象属性去重
     *
     * @param lists:     目标列表
     * @param fieldName: 对象属性名
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> districtBy(Collection<T> lists, String fieldName) {
        Set<KeyMapper<T>> keyMappers = new HashSet<>(Mapper.keyMappers(lists, fieldName));
        return keyMappers.stream().map(v -> v.obj).collect(Collectors.toList());
    }

    /**
     * 对目标列表按对象属性升序排序
     *
     * @param lists:       目标列表
     * @param compareFunc: 排序方法
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> sortIntBy(Collection<T> lists, ToIntFunction<T> compareFunc) {
        return lists.stream().sorted(Comparator.comparingInt(compareFunc)).collect(Collectors.toList());
    }


    /**
     * 对目标列表按对象属性降序排序
     *
     * @param lists:       目标列表
     * @param compareFunc: 排序方法
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> sortIntByDesc(Collection<T> lists, ToIntFunction<T> compareFunc) {
        return lists.stream().sorted((o1, o2) -> Integer.compare(compareFunc.applyAsInt(o2), compareFunc.applyAsInt(o1))).collect(Collectors.toList());
    }


    /**
     * 对目标列表按对象属性升序排序
     *
     * @param lists:       目标列表
     * @param compareFunc: 排序方法
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> sortLongBy(Collection<T> lists, ToLongFunction<T> compareFunc) {
        return lists.stream().sorted(Comparator.comparingLong(compareFunc)).collect(Collectors.toList());
    }

    /**
     * 对目标列表按对象属性降序排序
     *
     * @param lists:       目标列表
     * @param compareFunc: 排序方法
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> sortLongByDesc(Collection<T> lists, ToLongFunction<T> compareFunc) {
        return lists.stream().sorted((o1, o2) -> Long.compare(compareFunc.applyAsLong(o2), compareFunc.applyAsLong(o1))).collect(Collectors.toList());
    }


    /**
     * 对目标列表按对象属性升序排序
     *
     * @param lists:       目标列表
     * @param compareFunc: 排序方法
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> sortDoubleBy(Collection<T> lists, ToDoubleFunction<T> compareFunc) {
        return lists.stream().sorted(Comparator.comparingDouble(compareFunc)).collect(Collectors.toList());
    }

    /**
     * 对目标列表按对象属性降序排序
     *
     * @param lists:       目标列表
     * @param compareFunc: 排序方法
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> sortDoubleByDesc(Collection<T> lists, ToDoubleFunction<T> compareFunc) {
        return lists.stream().sorted((o1, o2) -> Double.compare(compareFunc.applyAsDouble(o2), compareFunc.applyAsDouble(o1))).collect(Collectors.toList());
    }


    private static <T> Triple<Set<IDMapper<T>>, Set<IDMapper<T>>, Set<IDMapper<T>>> leftRightAllIDMapper(Collection<T> list1, Collection<T> list2) {
        Set<IDMapper<T>> idMappers1 = new HashSet<>(Mapper.idMappers(list1));
        Set<IDMapper<T>> idMappers2 = new HashSet<>(Mapper.idMappers(list2));
        Set<IDMapper<T>> idMappersAll = new HashSet<IDMapper<T>>() {{
            addAll(new HashSet<>(Mapper.idMappers(list1)));
            addAll(new HashSet<>(Mapper.idMappers(list2)));
        }};
        return new Triple<>(idMappers1, idMappers2, idMappersAll);
    }

    private static <T> Triple<Set<KeyMapper<T>>, Set<KeyMapper<T>>, Set<KeyMapper<T>>> leftRightAllKeyMapper(Collection<T> list1, Collection<T> list2, String... key) {
        Set<KeyMapper<T>> keyMappers1 = new HashSet<>(Mapper.keyMappers(list1, key));
        Set<KeyMapper<T>> keyMappers2 = new HashSet<>(Mapper.keyMappers(list2, key));
        Set<KeyMapper<T>> keyMappersAll = new HashSet<KeyMapper<T>>() {{
            addAll(new HashSet<>(Mapper.keyMappers(list1, key)));
            addAll(new HashSet<>(Mapper.keyMappers(list2, key)));
        }};
        return new Triple<>(keyMappers1, keyMappers2, keyMappersAll);
    }


    /**
     * 按两个列表id的并集返回一个新列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> unionIDAll(Collection<T> list1, Collection<T> list2) {
        Set<IDMapper<T>> idMappersAll = new HashSet<IDMapper<T>>() {{
            addAll(new HashSet<>(Mapper.idMappers(list1)));
            addAll(new HashSet<>(Mapper.idMappers(list2)));
        }};

        return idMappersAll.stream().map(v -> v.obj).collect(Collectors.toList());
    }


    /**
     * 按两个列表id的交集返回一个新列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> unionID(Collection<T> list1, Collection<T> list2) {
        Triple<Set<IDMapper<T>>, Set<IDMapper<T>>, Set<IDMapper<T>>> idMapper = Streams.leftRightAllIDMapper(list1, list2);
        return idMapper.getThird().stream().filter(v -> idMapper.getFirst().contains(v) && idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());
    }


    /**
     * 按两个列表id的仅在列表1中，不在列表2中,返回一个新列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> unionIDLeft(Collection<T> list1, Collection<T> list2) {
        Triple<Set<IDMapper<T>>, Set<IDMapper<T>>, Set<IDMapper<T>>> idMapper = Streams.leftRightAllIDMapper(list1, list2);
        return idMapper.getThird().stream().filter(v -> idMapper.getFirst().contains(v) && !idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());
    }


    /**
     * 按两个列表id的不在列表1中，仅在列表2中,返回一个新列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> unionIDRight(Collection<T> list1, Collection<T> list2) {
        Triple<Set<IDMapper<T>>, Set<IDMapper<T>>, Set<IDMapper<T>>> idMapper = Streams.leftRightAllIDMapper(list1, list2);
        return idMapper.getThird().stream().filter(v -> !idMapper.getFirst().contains(v) && idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());
    }


    /**
     * 按两个列表key的并集返回一个新列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> unionKeyAll(Collection<T> list1, Collection<T> list2, String... key) {
        Set<KeyMapper<T>> keyMappersAll = new HashSet<KeyMapper<T>>() {{
            addAll(new HashSet<>(Mapper.keyMappers(list1, key)));
            addAll(new HashSet<>(Mapper.keyMappers(list2, key)));
        }};

        return keyMappersAll.stream().map(v -> v.obj).collect(Collectors.toList());
    }


    /**
     * 按两个列表key的交集返回一个新列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> unionKey(Collection<T> list1, Collection<T> list2, String... key) {
        Triple<Set<KeyMapper<T>>, Set<KeyMapper<T>>, Set<KeyMapper<T>>> idMapper = Streams.leftRightAllKeyMapper(list1, list2, key);
        return idMapper.getThird().stream().filter(v -> idMapper.getFirst().contains(v) && idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());
    }


    /**
     * 按两个列表key的仅在列表1中，不在列表2中,返回一个新列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> unionKeyLeft(Collection<T> list1, Collection<T> list2, String... key) {
        Triple<Set<KeyMapper<T>>, Set<KeyMapper<T>>, Set<KeyMapper<T>>> idMapper = Streams.leftRightAllKeyMapper(list1, list2, key);
        return idMapper.getThird().stream().filter(v -> idMapper.getFirst().contains(v) && !idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());
    }


    /**
     * 按两个列表key的不在列表1中，仅在列表2中,返回一个新列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Collection<T> unionKeyRight(Collection<T> list1, Collection<T> list2, String... key) {
        Triple<Set<KeyMapper<T>>, Set<KeyMapper<T>>, Set<KeyMapper<T>>> idMapper = Streams.leftRightAllKeyMapper(list1, list2, key);
        return idMapper.getThird().stream().filter(v -> !idMapper.getFirst().contains(v) && idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());
    }


    /**
     * 依次返回 仅在list1中，不在list2中的列表; 同时在list1,list2中的列表; 仅在list2中，不在list1中的列表
     *
     * @param list1 :       目标列表1
     * @param list2 :       目标列表2
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Triple<Collection<T>, Collection<T>, Collection<T>> unionKeyLeftMiddleRight(Collection<T> list1, Collection<T> list2, String... key) {
        Triple<Set<KeyMapper<T>>, Set<KeyMapper<T>>, Set<KeyMapper<T>>> idMapper = Streams.leftRightAllKeyMapper(list1, list2, key);
        Collection<T> left = idMapper.getThird().stream().filter(v -> idMapper.getFirst().contains(v) && !idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());
        Collection<T> middle = idMapper.getThird().stream().filter(v -> idMapper.getFirst().contains(v) && idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());
        Collection<T> right = idMapper.getThird().stream().filter(v -> !idMapper.getFirst().contains(v) && idMapper.getSecond().contains(v)).map(v -> v.obj).collect(Collectors.toList());

        return new Triple<>(left, middle, right);
    }


    /**
     * 对列表指定的所有子元素id值返回一个新列表
     *
     * @param lists:  目标列表
     * @param idFunc: 目标id字段
     * @return 合并后的一个新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <K,V extends Number> List<V> ids(List<K> lists, Function<K, V> idFunc) {
        return lists.stream().map(idFunc).collect(Collectors.toList());
    }

    /**
     * 对列表指定的所有子元素key值返回一个新列表
     *
     * @param lists:  目标列表
     * @param keyFunc: 目标key字段
     * @return 合并后的一个新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <K> List<String> keys(List<K> lists, Function<K, String> keyFunc) {
        return lists.stream().map(keyFunc).collect(Collectors.toList());
    }

    /**
     * 对列表指定的所有子元素(一个列表)合并成一个新列表
     *
     * @param lists:       目标列表
     * @param subListFunc: 目标子列表
     * @return 合并后的一个新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T, R> List<R> listFlatMap(Collection<T> lists, Function<T, List<R>> subListFunc) {
        List<R> records = new ArrayList<>();
        lists.forEach(v -> {
            records.addAll(subListFunc.apply(v));
        });
        return records;
    }

    /**
     * 对列表指定的所有子元素(一个数组)合并成一个新列表
     *
     * @param lists:    目标列表
     * @param splitter: 目标数组，通常是String.split 的拆分结果
     * @return 合并后的一个新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T, R> List<R> arrayFlatMap(Collection<T> lists, Function<T, R[]> splitter) {
        List<R> records = new ArrayList<>();
        lists.forEach(v -> {
            List<R> ll = Stream.of(splitter.apply(v)).filter(vv -> !Objects.isNull(vv)).collect(Collectors.toList());
            records.addAll(ll);
        });

        return records;
    }

    /**
     * 对列表指定的所有子元素(一个String数组)合并成一个id列表
     *
     * @param lists:    目标列表
     * @param splitter: 目标数组，通常是String.split 的拆分结果
     * @return 合并后的一个id列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> List<Long> arrayIdsFlatMap(Collection<T> lists, Function<T, String[]> splitter) {
        List<Long> records = new ArrayList<>();
        lists.forEach(v -> {
            List<String> ll = Stream.of(splitter.apply(v)).filter(vv -> !StringUtils.isEmpty(vv)).collect(Collectors.toList());
            records.addAll(ll.stream().map(Long::parseLong).collect(Collectors.toList()));
        });

        return records;
    }

    /**
     * String数组转成Long列表
     *
     * @param array: 目标数组，通常是String.split 的拆分结果
     * @return 合并后的一个id列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static List<Long> arrayIdsToList(String[] array) {
        return Stream.of(array)
                .filter(vv -> !StringUtils.isEmpty(vv))
                .map(Long::parseLong)
                .collect(Collectors.toList());
    }

    /**
     * 对目标列表所有的子元素转换成Long格式
     *
     * @param lists: 目标列表
     * @return 转换后的新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> List<Long> toLongList(Collection<T> lists) {
        return lists.stream().map(v -> Long.parseLong(String.valueOf(v))).collect(Collectors.toList());
    }

    /**
     * 对目标列表所有的子元素转换成Double格式
     *
     * @param lists: 目标列表
     * @return 转换后的新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> List<Double> toDoubleList(Collection<T> lists) {
        return lists.stream().map(v -> Double.parseDouble(String.valueOf(v))).collect(Collectors.toList());
    }

    /**
     * 对目标列表所有的子元素转换成String格式
     *
     * @param lists: 目标列表
     * @return 转换后的新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> List<String> toStrList(Collection<T> lists) {
        return lists.stream().map(String::valueOf).collect(Collectors.toList());
    }

    /**
     * 对目标列表所有的子元素转换成JSON格式
     *
     * @param lists: 目标列表
     * @return 转换后的新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> List<String> toJsonList(Collection<T> lists) {
        return lists.stream().map(Beans::json).collect(Collectors.toList());
    }

    /**
     * 对目标列表所有的子元素转换成指定Class格式
     *
     * @param lists: 目标列表
     * @return 转换后的新列表
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <R> List<R> toObjList(List<String> lists, Class<R> clz) {
        return lists.stream().map(v -> Beans.beans(v, clz)).collect(Collectors.toList());
    }



    /**
     * 按predicate条件判断数组中是否存在符合条件的成员
     *
     * @param lists: 目标列表
     * @return 若任一成员符合条件，返回true, 否则返回false
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> boolean any(Collection<T> lists, Predicate<T> predicate) {
        return lists.stream().anyMatch(predicate);
    }


    /**
     * 按predicate条件判断数组中是否存在符合条件的成员
     *
     * @param lists: 目标列表
     * @return 若所有成员符合条件，返回true, 否则返回false
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> boolean all(Collection<T> lists, Predicate<T> predicate) {
        return lists.stream().allMatch(predicate);
    }


    /**
     * 数组拷贝
     *
     * @param lists: 目标列表
     * @return 拷贝的数组
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> List<T> clone(List<T> lists) {
        List<Object> dest = new ArrayList<>(Arrays.asList(new Object[lists.size()]));
        Collections.copy(dest, lists);
        return (List<T>) dest;
    }

    /**
     * 数组逆序
     *
     * @param lists: 目标列表
     * @return 找到的成员，没找到即为Optional.empty()
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> List<T> reverse(List<T> lists) {
        List<T> dest = Streams.clone(lists);
        Collections.reverse(dest);
        return dest;
    }


    /**
     * 按predicate条件在数组中查找第一个符合条件的成员
     *
     * @param lists: 目标列表
     * @return 找到的成员，没找到即为Optional.empty()
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Optional<T> find(Collection<T> lists, Predicate<T> predicate) {
        for (T l : lists) {
            if (predicate.test(l)) {
                return Optional.of(l);
            }
        }

        return Optional.empty();
    }


    /**
     * 按predicate条件在数组中从后往前查找第一个符合条件的成员
     *
     * @param lists: 目标列表
     * @return 找到的成员，没找到即为Optional.empty()
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> Optional<T> findLast(List<T> lists, Predicate<T> predicate) {
        Collection<T> listReverse = Streams.reverse(lists);
        for (T l : listReverse) {
            if (predicate.test(l)) {
                return Optional.of(l);
            }
        }

        return Optional.empty();
    }


    /**
     * 计算列表指定成员的最大值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalInt maxIntBy(Collection<T> lists, ToIntFunction<? super T> func) {
        return lists.stream().mapToInt(func).max();
    }

    /**
     * 计算列表指定成员的最大值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalDouble maxDoubleBy(Collection<T> lists, ToDoubleFunction<? super T> func) {
        return lists.stream().mapToDouble(func).max();
    }

    /**
     * 计算列表指定成员的最大值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalLong maxLongBy(Collection<T> lists, ToLongFunction<? super T> func) {
        return lists.stream().mapToLong(func).max();
    }


    /**
     * 计算列表指定成员的最小值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalInt minIntBy(Collection<T> lists, ToIntFunction<? super T> func) {
        return lists.stream().mapToInt(func).min();
    }

    /**
     * 计算列表指定成员的最小值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalDouble minDoubleBy(Collection<T> lists, ToDoubleFunction<? super T> func) {
        return lists.stream().mapToDouble(func).min();
    }

    /**
     * 计算列表指定成员的最小值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalLong minLongBy(Collection<T> lists, ToLongFunction<? super T> func) {
        return lists.stream().mapToLong(func).min();
    }


    /**
     * 计算列表指定成员的平均值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalDouble avgIntBy(Collection<T> lists, ToIntFunction<? super T> func) {
        return lists.stream().mapToInt(func).average();
    }

    /**
     * 计算列表指定成员的平均值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalDouble avgDoubleBy(Collection<T> lists, ToDoubleFunction<? super T> func) {
        return lists.stream().mapToDouble(func).average();
    }

    /**
     * 计算列表指定成员的平均值
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T> OptionalDouble avgLongBy(Collection<T> lists, ToLongFunction<? super T> func) {
        return lists.stream().mapToLong(func).average();
    }


    /**
     * 连接列表指定成员
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T, R> String join(Collection<T> lists, Function<T, R> func) {
        List<String> joinLists = lists.stream().map(v -> String.valueOf(func.apply(v))).collect(Collectors.toList());
        return String.join(",", joinLists);
    }

    /**
     * 连接列表指定成员
     *
     * @param lists : 目标列表
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <T, R> String joinByDelimiter(Collection<T> lists, Function<T, R> func, String delimiter) {
        List<String> joinLists = lists.stream().map(v -> String.valueOf(func.apply(v))).collect(Collectors.toList());
        return String.join(delimiter, joinLists);
    }

    /**
     *  交换map 的k,v 值，转换为另一个map
     *
     * @param maps : 目标map
     * @return
     * @author Daizhiqiang
     * @date 2019/7/1 14:10
     */
    public static <K, V> Map<V,K> swapMapKV(Map<K,V> maps) {
        HashMap<V, K> resultMaps = new HashMap<>();
        maps.forEach((k,v)->{
            resultMaps.put(v,k);
        });
        return resultMaps;
    }
}

